/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
 * Description: 获取动态库中hns接口函数的适配接口.
 * Author: lzh
 * Create: 2024-09-10
 */

#include "dlhns_function.h"

#include <string>
#include <map>
#include "hccl_dl.h"
#include "log.h"


namespace hccl {

DlHnsFunction &DlHnsFunction::GetInstance()
{
    static DlHnsFunction hcclDlHnsFunction;
    return hcclDlHnsFunction;
}

DlHnsFunction::DlHnsFunction() : handle_(nullptr)
{
}

DlHnsFunction::~DlHnsFunction()
{
    if (handle_ != nullptr) {
        (void)HcclDlclose(handle_);
        handle_ = nullptr;
    }
}

HcclResult DlHnsFunction::DlHnsFunctionRoceInit()
{
    dlHnsIbvExtPostSend = (int(*)(struct ibv_qp *, struct ibv_send_wr *,
        struct ibv_send_wr **, struct IbvPostSendExtAddt *,
        struct IbvPostSendExtResp *))HcclDlsym(handle_, "ibv_ext_post_send");
    CHK_SMART_PTR_NULL(dlHnsIbvExtPostSend);

    dlHnsIbvExpPostSend = (int(*)(struct ibv_qp *, struct ibv_send_wr *,
        struct ibv_send_wr **, struct WrExpRsp *))HcclDlsym(handle_, "ibv_exp_post_send");
    CHK_SMART_PTR_NULL(dlHnsIbvExpPostSend);
    return HCCL_SUCCESS;
}

HcclResult DlHnsFunction::DlHnsFunctionSoInit()
{
    if (handle_ == nullptr) {
        handle_ = HcclDlopen("libhns-rdmav25.so", RTLD_NOW);
        if (handle_ != nullptr) {
            return HCCL_SUCCESS;
        }
        return HCCL_E_INTERNAL;
    } else {
            HCCL_INFO("roce_user_api dlopen again!");
    }
    return HCCL_SUCCESS;
}

HcclResult DlHnsFunction::DlHnsFunctionInit()
{
    std::lock_guard<std::mutex> lock(handleMutex_);
    CHK_RET(DlHnsFunctionSoInit());
    CHK_RET(DlHnsFunctionRoceInit());

    return HCCL_SUCCESS;
}

}